home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / pgp23src.zip / LMUL.H < prev    next >
C/C++ Source or Header  |  1993-05-09  |  2KB  |  74 lines

  1. /*
  2.  * lmul.h  - Macros for doing a n x n -> 2N multiply.
  3.  *
  4.  * Included by R3000.C, for use in Philip Zimmermann's PGP program.
  5.  * Implemented by Castor Fu, Sep 1992.
  6.  *
  7.  * Define PATCH_ASM if you want to patch the assembly code yourself. . .
  8.  *
  9.  * Currently has support for mips, i386 and 680[2+]0 under GCC.
  10.  *
  11.  * The general (and generally undesired ) case manually
  12.  * performs the multiply by splitting the numbers up into two pieces. . .
  13.  *
  14.  * lmul(i1,i2,ol,oh) takes the product of i1, i2 and yields ol, oh
  15.  * the lower and upper halves of the result.
  16.  */
  17.  
  18. #ifdef PATCH_ASM
  19. #define    lmul(i1,i2,ol, oh)    (ol=(i1)*(i2), oh=(i1)^(i2))
  20. #else
  21.  
  22. #if    defined(__GNUC__) && defined(mips)  && defined(MUNIT32)
  23. #define lmul(a,b,xl,xh) \
  24. { \
  25.     asm("multu    %2, %3\n\tmflo    %0\n\tmfhi    %1" : \
  26.         "=d" (xl) , "=d" (xh) : "d" (a), "d" (b)); \
  27. }
  28. #else 
  29. #if    defined(__GNUC__) && defined(mc68020)  && defined(MUNIT32)
  30. #define    lmul(a,b,xl,xh) \
  31. {\
  32.     xl = a; \
  33.     asm("mulul    %3, %1:%0" : "=d" (xl) , "=d" (xh) : "0" (xl) , "d" (b)); \
  34. }
  35. #else
  36. #if    defined(__GNUC__) && defined(i386)  && defined(MUNIT32)
  37. #define    lmul(a,b,xl,xh)    asm("mull %3":"=a" (xl),"=d" (xh):"0" (a),"g" (b))
  38. #else
  39.  
  40. #define MUNITHMASK    (((unsigned long)1 <<(MUNITSIZE/2)) - 1)
  41.  
  42. #ifdef MUNIT16 
  43. #define lmul(a,b,xl,xh) \
  44. {\
  45.     unsigned long XX = (unsigned long) (a)*(b); \
  46.     xl = XX & 0xffff; \
  47.     xh = XX >> 16; \
  48. }
  49.  
  50. #else 
  51. #define    lmul(a,b,xl, xh)  \
  52. {\
  53.    MULTUNIT Xaa, Xbb, Xal, Xah, Xbl, Xbh, Xx1,Xx2,Xx3,Xx4,Xx5,Xx6; \
  54.      Xaa= (a); Xbb = (b); Xal = Xaa&MUNITHMASK; Xah = Xaa>>(MUNITSIZE/2); \
  55.      Xbl = Xbb&MUNITHMASK; Xbh = Xbb>>(MUNITSIZE/2); \
  56.     Xx1 = Xal*Xbl; \
  57.     Xx2 = Xah*Xbl; \
  58.     Xx3 = Xal*Xbh; \
  59.     Xx4 = Xah*Xbh; \
  60.     Xx5 = Xx2+Xx3; \
  61.     Xx4 += ((MULTUNIT) (Xx5 < Xx2)) << (MUNITSIZE/2); \
  62.     Xx6 = Xx1 + (Xx5 << (MUNITSIZE/2)); \
  63.     Xx4 += (Xx6 < Xx1) + (Xx5>>(MUNITSIZE/2)); \
  64.  \
  65.  \
  66.     xl = Xx6; \
  67.     xh = Xx4; \
  68. }
  69. #endif
  70. #endif
  71. #endif
  72. #endif
  73. #endif /* PATCH_ASM */
  74.